home *** CD-ROM | disk | FTP | other *** search
- ;
- ; ACountPix.asm
- ; Pascal Usage: Function ACountPix( theRegion:RgnHandle) : LongInt;
- ; This functiion emulates CountPix
- ; Written by Thomas W. Moore, Ph.D. and Stephen Dubin, V.M.D., Ph.D.
- ; Copyright © 1987
-
- XDEF ACountPix
- XREF myBUF
- ;--------------------------------- INCLUDES -------------------------------
-
- Include Traps.D ; Use System and ToolBox traps
- Include ToolEqu.D ; Use ToolBox equates
-
-
-
- ACountPix:
- link A6,#0 ; set up frame pointer
- movem.l A0-A3/D0-D7,-(A7) ; save the world
- clr.l -(A7) ; make room on stack for result
- movea.l 8(A6),A0 ; region handle into A0
- movea.l (A0),A0 ; dereference => pointer in A0
- clr.l D7 ; set area to zero
- lea myBUF(A5),A1 ; lowest address of x list
-
- rectcheck: ; see whether it is a rect and if so - do the job here
- cmpi.w #10,(A0) ; is this a single rectangle
- bne.s morework ; if not do the big job
- move.w 4(A0),D1 ; left
- move.w 8(A0),D2 ; right
- move.w 2(A0),D3 ; top
- move.w 6(A0),D4 ; bottom
- sub.w D1,D2 ; width
- sub.w D3,D4 ; height
- mulu.w D2,D4 ; area in D4
- move.w D4,D7 ; lower word into D7
- bra done
-
- morework: ; get ready for some serious work
- lea 10(A0),A0 ; beginning of region info
- clr.l D4 ;
- clr.l D2 ;
- move.l #512,D3 ; size of buffer to hold ordered list of x values
- adda.l D3,A1 ; highest address in buffer
- movea.l A1,A2 ; copy in A2
- movea.l A1,A3 ; another in A3
- move.w #-1,(A1) ; -1 in highest x address so that 1st x entry will be greater
-
- gety: ; read in y coordinate of next horizontal boundary ;
- move.w (A0)+, D3 ; latest y value
- jsr calc ;
-
- getx:
- move.w (A0)+,D1 ; new x value
- cmpi.w #$7fff,D1 ; flag indicates no more x values at this y
- bne storex ; if no flag, it is a new x
- move.w (A0),D1 ; next word of region info
- cmpi.w #$7fff,D1 ; all done?
- beq done ; yes go home
- bra gety ; no, get next y
-
- storex: ; place new x value in proper place in ordered list
- movea.l A3,A1 ; A3 points to highest x value in ordered list
- cmp.w (A1),D1 ; compare new x value to largest entry
- bne s1 ; if not equal, it must be added to list
- addq #2,A3 ; if match, remove from list
- bra getx ; next x
-
- s1:
- lea -2(A3),A3 ; add a space at high end of list for new x
- bgt.s insert ; if new x value is greatest, put it on top
-
- mkroom: ; new x is not greatest so we must move list values up to make room
- move.w (A1)+,-4(A1) ; move data up (1 word net distance)
- cmp.w (A1),D1 ; compare next list entry
- beq.s remove ; if it matches, remove it
- bcc.s insert ; it is greater, so put it above
- cmpa.l A1,A2 ; are we at bottom?
- bne mkroom ; no, move another one up
-
- insert: ; insert new x value in ordered place in list
- move.w D1,-(A1) ; insert above present location
- bra getx ;
-
- remove: ; erases an entry from the list
- subq #2,A1 ; point to next higher
-
- r1:
- cmpa.l A1,A3 ; is it the top?
- beq shrink ; yes so exit
- move.w -(A1),4(A1) ; move greater x values down to replace
- bra r1 ; value removed
-
- shrink:
- addq #4,A3 ; if a match occurred, list shrinks by 2 words
- bra getx ; one that we didn't insert and one that we erased
-
- calc: ; determine new Height
- sub.w D3,D4 ; Y old - Y new
- neg.w D4 ; Height of the rectangle(s)
-
- newW: ; prepare for Width calculation
- clr.l D2 ; Will receive width
- clr.l D1 ; work reg
- movea.l A2,A1 ; reset A1 to point to least x value in list
-
- dx: ; check to see if all x pairs have been used.
- ; multiply H x W and add to area
- cmpa.l A1,A3 ; A3 points to greatest x value in list
- bne morex ; if not equal, not all x's have been used
- mulu D4,D2 ; H x W
- add.l D2,D7 ; add to accumulating area
- move.w D3,D4 ; for next time
- rts
-
- morex: ; subtracts x values in pairs adding differences
- ; to accumulating W
- move.w -(A1),D1 ; Xi (lower x value of a pair)
- sub.w -(A1),D1 ; Xi - Xi+1 (length of a horizontal boundary segment)
- neg.w D1 ; Xi+1 - Xi (correct sign)
- add.w D1,D2 ; W (add to accumulating width)
- bra dx ;
-
- done:
- move.l D7,12(A6) ; store result "under" the last parameter
- movem.l (A7)+,A0-A3/D0-D7 ; restore registers
- unlk A6 ; restore original stack
- move.l (A7)+,A0 ; get return address
- addq.l #4,A7 ; remove parameters
- jmp (A0) ; return this way
-
- end
-
-
-
-
-
-
-
-